package pri.zxx.webdemo.controllers;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.RedisStringCommands;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.types.Expiration;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import pri.zxx.webdemo.entity.vo.ResultData;
import pri.zxx.webdemo.utils.TimeUtils;

import java.util.Map;
import java.util.Random;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * @author Twilight
 * @desc
 * @createTime 2019-06-16-14:00
 */
@RestController
@Tag(name =  "LEARN_DEMO-redis 测试接口")
@RequestMapping(value = "/redis")
@Slf4j
public class RedisController {
    private static String[] types = new String[]{"A", "B", "C", "D", "E", "F", "G", "H"};
    @Autowired
    private RedisTemplate redisTemplate;

    @Operation(summary = "redis测试")
    @GetMapping(value = "/test")
    public void myTest() throws InterruptedException {
        ThreadPoolExecutor ex = new ThreadPoolExecutor(10, 20, 500, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(1));
        for (int j = 0; j < 50; j++) {
            for (int i = 0; i < 9; i++) {
                int finalJ = j;
                ex.execute(() -> {
                    for (int k = 0; k < 500; k++) {
                        int i1 = new Random().nextInt(8);
                        this.incr(types[i1], finalJ);
                    }
                });
            }
            int finalJ1 = j;
            ex.execute(() -> {
                for (int i = 0; i < 50; i++) {
                    Map map = this.get(finalJ1);
                    System.out.println(map);
                    System.out.println("------------------");
                }
            });
            TimeUnit.SECONDS.sleep(2);
        }
    }

    public void incr(String type, Integer num) {
        redisTemplate.opsForHash().increment(num + "-map", type, 1);
    }

    public Map get(Integer num) {
        return redisTemplate.opsForHash().entries(num + "-map");
    }


    @GetMapping(value = "/addLock")
    public ResultData<String> lock(String key) {
        boolean flag = redisTemplate.getConnectionFactory().getConnection().set(key.getBytes(), "value".getBytes(), Expiration.seconds(5), RedisStringCommands.SetOption.SET_IF_ABSENT);
        if (flag) {
            log.warn("---->>lock");
            TimeUtils.pause(0, 3, 0);
        } else {
            return ResultData.fail("获取锁失败");
        }
        Boolean delete = redisTemplate.delete(key);
        log.warn("---->>release lock:{}", delete);
        return ResultData.success();
    }

}
